package fem2.gui;

import fem2.gui.pm.HofemPipelineFactory;
import inf.swing.DoubleTextField;
import inf.vtk.pm.CurvesPipeline;
import inf.vtk.pm.PipelineCollection;
import inf.vtk.pm.SolidElementsPipeline;
import inf.vtk.pm.uiswing.ActorCheckBox;
import inf.vtk.pm.uiswing.LeftBox;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class DisplacementPanel extends LeftBox {

	private static final long serialVersionUID = 1L;

	public static double DEFAULT_SCALE = 100;

	private PipelineCollection pipelineCollection_;
	private JCheckBox visibleCB_;
	private ScalePanel scalePanel_;

	public DisplacementPanel(PipelineCollection pipelineCollection) {
		pipelineCollection_ = pipelineCollection;

		setBorder(BorderFactory.createTitledBorder("Displacements"));
		add(getVisibleCB());
		add(getScalePanel());
	}

	public CurvesPipeline getCurvesPipeline() {
		return (CurvesPipeline) pipelineCollection_
				.getPart(HofemPipelineFactory.PL_EDGES);
	}

	private ScalePanel getScalePanel() {
		if (scalePanel_ == null) {
			scalePanel_ = new ScalePanel();
			final DoubleTextField dtf = scalePanel_.getDoubleTextField();

			dtf.setDoubleValue(DEFAULT_SCALE);
			setScale(false, DEFAULT_SCALE);

			dtf.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					setScale(true, dtf.getDoubleValue());
				}
			});
			dtf.addChangeListener(new ChangeListener() {

				@Override
				public void stateChanged(ChangeEvent e) {
					setScale(true, dtf.getDoubleValue());
				}
			});
		}
		return scalePanel_;
	}

	public SolidElementsPipeline getSolidsPipeline() {
		return (SolidElementsPipeline) pipelineCollection_
				.getPart(HofemPipelineFactory.PL_FACES);
	}

	private JCheckBox getVisibleCB() {
		if (visibleCB_ == null) {
			visibleCB_ = new ActorCheckBox("Visible", getCurvesPipeline(),
					getCurvesPipeline().getActorManager(
							CurvesPipeline.ACTOR_DISPLACED_CURVES),
					getSolidsPipeline().getActorManager(
							SolidElementsPipeline.ACTOR_ELEMENTS_CC));
		}
		return visibleCB_;
	}

	private void setScale(boolean render, double s) {
		getCurvesPipeline().setScaleFactor(s);
		getSolidsPipeline().setDisplacementScaleFactor(s);
		if (render) {
			getCurvesPipeline().render();
		}
	}
}
